from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
from django.conf import settings
from functools import partial

# from django.contrib.auth.models import User
from django.db.models.signals import post_save


class RatioConfig(models.Model):
    name = models.CharField(max_length=45, blank=False, default='')
    note = models.CharField(max_length=45, blank=True, default='')
    ratio = models.FloatField(blank=False, default=0.0)

    class Meta:
        managed = False
        db_table = 'ratio_config'
        verbose_name = 'ratio_config'
        verbose_name_plural = 'ratio_config'

    def __str__(self):
        return self.name


class User(AbstractUser):
    sin_no = models.CharField(max_length=64, blank=True, default='')
    dob = models.DateField(max_length=90, blank=True, null=True)
    address = models.CharField(max_length=100, blank=True, default='')
    ctc_phone = models.CharField(max_length=45, blank=True, default='')

    class Meta(AbstractUser.Meta):
        swappable = 'AUTH_USER_MODEL'
        db_table = 'auth_user'


class AbstractPayroll(models.Model):
    # HOURS = ((i, "%s hours" % i) for i in range(50, 91, 10))
    WAGE = ((i, "$ %d" % i) for i in range(15, 40))
    VACATION = ((i, "%d %%" % i) for i in range(4, 7, 2))

    user = models.ForeignKey(settings.AUTH_USER_MODEL, models.DO_NOTHING, verbose_name='Employee')
    hours = models.DecimalField(max_digits=8, decimal_places=2, blank=False, default=80.00, )
    wage_per_hr = models.IntegerField(blank=False, default=20, choices=WAGE, )
    vacation_pay_ratio = models.IntegerField(blank=False, default=6, choices=VACATION, verbose_name='ratio')
    federal_tax = models.DecimalField(max_digits=8, decimal_places=2, blank=False, default=0.00, )
    provincial_tax = models.DecimalField(max_digits=8, decimal_places=2, blank=False, default=0.00, )
    cpp = models.DecimalField(db_column='CPP', max_digits=8, decimal_places=2, blank=False,
                              default=0.00, )  # Field name made lowercase.
    ei = models.DecimalField(db_column='EI', max_digits=8, decimal_places=2, blank=False,
                             default=0.00, )  # Field name made lowercase.
    mtime = models.DateTimeField(auto_now=True, editable=False, )
    ctime = models.DateTimeField(auto_now_add=True, editable=False, )

    class Meta:
        abstract = True

    def __str__(self):
        return "%d hours-$%f-%d%%" % (self.hours, self.wage_per_hr, self.vacation_pay_ratio)

    def wage_income(self):
        return self.hours * self.wage_per_hr

    def vacation_pay(self):
        return self.wage_income() * self.vacation_pay_ratio / 100

    def total_cash_income(self):
        return self.wage_income() + self.vacation_pay()

    def total_tax(self):
        return self.federal_tax + self.provincial_tax

    def total_deductions(self):
        return self.total_tax() + self.cpp + self.ei

    def net_amount(self):
        return self.total_cash_income() - self.total_deductions()

    total_tax.short_description = 'Tax'
    total_cash_income.short_description = 'Gross'
    total_deductions.short_description = 'Withheld'
    net_amount.short_description = 'Net Pay'


class Payroll(AbstractPayroll):
    class Meta:
        managed = False
        db_table = 'payroll'
        verbose_name = 'payroll'
        verbose_name_plural = 'payroll'


def date_add(days=-13):
    import datetime
    # 获取当前时间
    now_time = timezone.now()
    # 当前时间减去一天 获得昨天当前时间
    return now_time + datetime.timedelta(days=days)


class PayrollLog(AbstractPayroll):
    period_from = models.DateField(blank=False, default=partial(date_add, -13))
    period_to = models.DateField(blank=False, default=timezone.now)
    pay_date = models.DateField(blank=False, default=timezone.now, verbose_name='Date')
    cheque_no = models.CharField(max_length=64, blank=False, default='', verbose_name='Cheque No.')
    note = models.CharField(max_length=90, blank=True, default='')

    class Meta:
        managed = False
        db_table = 'payroll_log'
        verbose_name = 'payroll'
        verbose_name_plural = 'payroll'

    def __str__(self):
        return "%s: %d hours-$%f-%d%%" % (
            self.user.username, self.hours, self.wage_per_hr, self.vacation_pay_ratio)


def signal_post_save_payroll():
    pass

# post_save.connect(signal_post_save_payroll,)
